<?php


namespace kyd\kyd_extend\pay\wxpay;


class BaseWxpay
{

    const UNIFIEDORDER = 'https://api.mch.weixin.qq.com/pay/unifiedorder'; //无需更改 统一下单API地址

    private $KEY = ''; //支付秘钥需要更改成自己的
    private $APPID = '';//APPID需要更改为自己的
    private $MCHID = '';//商户号需要更改成自己的
    private $SECRET = '';//开发者密码需要更改为自己的

    public function __construct($params) {

        $this->KEY = isset($params['KEY'])?$params['KEY']:'';
        $this->APPID = isset($params['APPID'])?$params['APPID']:'';
        $this->MCHID = isset($params['MCHID'])?$params['MCHID']:'';
        $this->SECRET = isset($params['SECRET'])?$params['SECRET']:'';

    }

    //获取签名
    public function getSign($arr){
        //去除数组的空值
        array_filter($arr);
        if(isset($arr['sign'])){
            unset($arr['sign']);
        }
        //排序
        ksort($arr);
        //组装字符
        $str = $this->arrToUrl($arr) . '&key=' . $this->KEY;
        //使用md5 加密 转换成大写
        return strtoupper(md5($str));
    }

    //获取带签名的数组
    public function setSign($arr){
        $arr['sign'] = $this->getSign($arr);
        return $arr;
    }

    //验证签名
    public function checkSign($arr){
        $sign = $this->getSign($arr);
        if($sign == $arr['sign']){
            return true;
        }else{
            return false;
        }
    }

    //数组转URL字符串 不带key
    public function arrToUrl($arr){
        return urldecode(http_build_query($arr));
    }

    //记录到文件
    public  function logs($file,$data){
        $data = is_array($data) ? print_r($data,true) : $data;
        file_put_contents('./logs/' .$file, $data);
    }

    public function getPost(){
        return file_get_contents('php://input');
    }

    //Xml 文件转数组
    public function XmlToArr($xml)
    {
        if($xml == '') return '';
        libxml_disable_entity_loader(true);
        $arr = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
        return $arr;
    }


    //获取公众号/小程序支付所需要的json数据
    public function getJsParams($prepay_id){
        $params = [
            'appId' => $this->APPID,
            'timeStamp' =>time(),
            'nonceStr' => md5(time()),
            'package' =>'prepay_id=' . $prepay_id,
            'signType' =>'MD5',
        ];
        $params['paySign'] = $this->getSign($params);
        return $params;
    }

    //数组转XML
    public function ArrToXml($arr)
    {
        if(!is_array($arr) || count($arr) == 0) return '';

        $xml = "<xml>";
        foreach ($arr as $key=>$val)
        {
            if (is_numeric($val)){
                $xml.="<".$key.">".$val."</".$key.">";
            }else{
                $xml.="<".$key."><![CDATA[".$val."]]></".$key.">";
            }
        }
        $xml.="</xml>";
        return $xml;
    }


    //post 字符串到接口
    public function postStr($url,$postfields){
        $ch =  curl_init();
        $params[CURLOPT_URL] = $url;    //请求url地址
        $params[CURLOPT_HEADER] = false; //是否返回响应头信息
        $params[CURLOPT_RETURNTRANSFER] = true; //是否将结果返回
        $params[CURLOPT_FOLLOWLOCATION] = true; //是否重定向
        $params[CURLOPT_POST] = true;
        $params[CURLOPT_SSL_VERIFYPEER] = false;//禁用证书校验
        $params[CURLOPT_SSL_VERIFYHOST] = false;
        $params[CURLOPT_POSTFIELDS] = $postfields;
        curl_setopt_array($ch, $params); //传入curl参数
        $content = curl_exec($ch); //执行
        curl_close($ch); //关闭连接
        return $content;
    }


    /**
     *
     *
     * 1.构建原始数据
     * 2.加入签名
     * 3.将数据转换为XML
     * 4.发送XML格式的数据到接口地址
     * $params = [
     *        'appid'=> $this->APPID,
     *        'mch_id'=> $this->MCHID,
     *        'nonce_str'=>md5(time()),
     *        'body'=> isset($paramsArr['body'])?$paramsArr['body']:"发货券",
     *        'out_trade_no'=>$paramsArr['out_trade_no'],
     *        'total_fee'=> $paramsArr['total_fee'],
     *        'spbill_create_ip'=>$_SERVER['REMOTE_ADDR'],
     *        'notify_url'=> $paramsArr['notify_url'],
     *        'trade_type'=>'JSAPI',
     *        'openid'    => $paramsArr['openid'],
     *    ];
     * @param $params
     * @return false|mixed|string
     */
    public function unifiedorder($params){
        //获取到带签名的数组
        $params = $this->setSign($params);
        //数组转xml
        $xml = $this->ArrToXml($params);
        //发送数据到统一下单API地址
        $data = $this->postStr(self::UNIFIEDORDER, $xml);
        $arr = $this->XmlToArr($data);
        if($arr['result_code'] == 'SUCCESS' && $arr['return_code'] == 'SUCCESS'){
            return $arr;
        }else{
            return false;
        }
    }

}
